HAL SDIO Typical use cases for migration ¶
This section provides information about the HAL SDIO Typical use cases for migration.
Note
The main SDIO API usage patterns—such as direct and extended transfers (polling or DMA), and function interrupt handling—remain largely unchanged for the user between HAL1 and HAL2. Most function names and parameters remain unchanged.
The most significant changes in HAL2 are in the card identification sequence during initialization, and also the callback registration and handling:
Configuration and card identification: In HAL1, the custom card identification required callback registration (see use case description for details); in HAL2, the identification function is passed as a pointer parameter to the configuration API
HAL_SDIO_SetConfig().Callback registration is unified and event-driven: Instead of separate TX and RX callbacks, HAL2 introduces a single transfer completion callback with an event parameter.
Use case: SDIO configuration and card identification sequence ¶
The card identification function performs communication with the SDIO card and extracts the card’s key information, needed before applying the user configurations and starting operation. Users can provide a custom identification sequence to handle device-specific requirements or vendor extensions that differ from the default flow.
|
HAL1 |
HAL2 |
|---|---|
|
In HAL1 (Callback Registration): User used to register his custom card identification function using
|
In HAL2 (Direct Parameter): The sequence is changed, there is no registration step and the user should pass the identification function directly as the third argument to
|
Code Snippet
|
HAL1 |
HAL2 |
|---|---|
hsdio.Instance = SDMMC1;
hsdio.Init = user_sdio_config;
/* Register custom card identification function if needed */
#if defined(USER_SDIO_USE_CUSTOM_IDENTIFY)
/* Register custom card identification function */
HAL_SDIO_RegisterIdentifyCardCallback(&hsdio,
USER_SDIO_IdentifyCard);
#else
/* Do nothing; use default card identification */
#endif
/* Continue with SDIO initialization and configuration */
HAL_SDIO_Init(&hsdio);
HAL_StatusTypeDef USER_SDIO_IdentifyCard(SDIO_HandleTypeDef *hsdio)
{
/* Custom card identification sequence */
.
..
...
return HAL_OK;
}
|
/* Perform SDIO driver initialization */
HAL_SDIO_Init(&hsdio, HAL_SDIO_CARD_1);
/* Perform SDIO configuration */
#if defined(USER_SDIO_USE_CUSTOM_IDENTIFY)
/* Provide custom identify card function */
HAL_SDIO_SetConfig(&hsdio,
&user_sdio_config,
USER_SDIO_IdentifyCard);
#else
/* Pass NULL as third param; use default card identification */
HAL_SDIO_SetConfig(&hsdio, &user_sdio_config, NULL);
#endif
hal_status_t USER_SDIO_IdentifyCard(hal_sdio_handle_t *hsdio)
{
/* Custom card identification sequence */
.
..
...
return HAL_OK;
}
|
Use case: SDIO direct transfer ¶
A direct I/O transfer accesses a single byte in an SDIO function register space and is commonly used for control/status registers (for example, reading an interrupt status register or writing a configuration value). The sequence and APIs remain unchanged between HAL1 and HAL2.
For example, an SDIO Wi‑Fi device may expose multiple functions where
user_io_func_nbr
selects the Wi‑Fi function; a direct transfer could then read a status register in the Wi‑Fi function or write a control register.
Code Snippet
|
HAL1/HAL2 |
|---|
uint8_t reg_value = 0U;
/* Read a single byte from a function register */
if (HAL_SDIO_ReadDirect(&hsdio,
user_io_func_nbr,
RegisterAddress,
®_value) != HAL_OK)
{
Error_Handler();
}
/* Update configuration register */
reg_value |= REG_ENABLE_MASK; /* Example: enable a specific feature */
/* Write back the updated value to the function register */
if (HAL_SDIO_WriteDirect(&hsdio,
user_io_func_nbr,
RegisterAddress,
reg_value) != HAL_OK)
{
Error_Handler();
}
|
Use case: SDIO extended polling transfer ¶
Extended polling transfers use
HAL_SDIO_WriteExtended()
and
HAL_SDIO_ReadExtended()
in blocking mode. The APIs remain unchanged between
HAL1 and HAL2. For example, an SDIO Wi‑Fi device may expose multiple functions where
user_io_func_nbr
selects
the Wi‑Fi function; an extended transfer could then transfer a TCP/IP packet in the Wi‑Fi function.
Code Snippet
|
HAL1/HAL2 |
|---|
/* Write BufferSize bytes to function user_io_func_nbr
at address IoAddress using Extended polling */
if (HAL_SDIO_WriteExtended(&hsdio,
user_io_func_nbr,
Write_IoAddress,
Buffer_Tx,
BufferSize,
TimeoutMs) != HAL_OK)
{
Error_Handler();
}
/* Read BufferSize bytes from function user_io_func_nbr
at address IoAddress using Extended polling */
if (HAL_SDIO_ReadExtended(&hsdio,
user_io_func_nbr,
Read_IoAddress,
Buffer_Rx,
BufferSize,
TimeoutMs) != HAL_OK)
{
Error_Handler();
}
|
Use case: SDIO extended DMA transfer ¶
The extended DMA transfer uses interrupts to handle transfer completion and errors. The sequence and APIs remain mostly unchanged between HAL1 and HAL2, with only changes in the callback registration and handling.
An SDIO Wi‑Fi device may expose multiple functions where
user_io_func_nbr
selects the Wi‑Fi function; an extended transfer could then
transfer a TCP/IP packet in the Wi‑Fi function.
|
HAL1 |
HAL2 |
|---|---|
|
Extended DMA transfer uses
|
Extended DMA transfer sequence is mostly unchanged, but callback registration is unified through
|
Code Snippet
|
HAL1 |
HAL2 |
|---|---|
/* Register the Tx and Rx Transfer complete callbacks */
HAL_SDIO_RegisterCallback(&hsdio,
HAL_SDIO_TX_CPLT_CB_ID,
USER_SDIO_TxCpltCallback);
HAL_SDIO_RegisterCallback(&hsdio,
HAL_SDIO_RX_CPLT_CB_ID,
USER_SDIO_RxCpltCallback);
/* Write BufferSize bytes to function user_io_func_nbr
at address IoAddress using Extended DMA */
HAL_SDIO_WriteExtended_DMA(&hsdio,
user_io_func_nbr,
Write_IoAddress,
Buffer_Tx,
BufferSize);
/* Wait for the Writing process to complete */
while (sdiotransfertx == 0)
{}
/* Read BufferSize bytes from function user_io_func_nbr
at address IoAddress using Extended DMA */
HAL_SDIO_ReadExtended_DMA(&hsdio,
user_io_func_nbr,
ReadIoAddress,
Buffer_Rx,
BufferSize);
/* Wait for the Reading process to complete */
while (sdiotransferrx == 0)
{}
void USER_SDIO_TxCpltCallback(SDIO_HandleTypeDef *hsdio) {
sdiotransfertx = 1;
}
void USER_SDIO_RxCpltCallback(SDIO_HandleTypeDef *hsdio) {
sdiotransferrx = 1;
}
|
/* Register the Tx and Rx Transfer complete callbacks */
HAL_SDIO_RegisterXferCpltCallback(&hsdio,
USER_SDIO_XferCallback);
/* Write BufferSize bytes to function user_io_func_nbr
at address IoAddress using Extended DMA */
HAL_SDIO_WriteExtended_DMA(&hsdio,
user_io_func_nbr,
Write_IoAddress,
Buffer_Tx,
BufferSize);
/* Wait for the Writing process to complete */
while (sdiotransfertx == 0)
{}
/* Read BufferSize bytes from function user_io_func_nbr
at address IoAddress using Extended DMA */
HAL_SDIO_ReadExtended_DMA(&hsdio,
user_io_func_nbr,
Read_IoAddress,
Buffer_Rx,
BufferSize);
/* Wait for the Reading process to complete */
while (sdiotransferrx == 0)
{}
void USER_SDIO_XferCallback(hal_sdio_handle_t *hsdio,
hal_sdio_event_cb_t cb_event) {
switch (cb_event) {
case HAL_SDIO_EVENT_CB_TX_CPLT:
sdiotransfertx = 1;
break;
case HAL_SDIO_EVENT_CB_RX_CPLT:
sdiotransferrx = 1;
break;
default: break;
}
}
|